package com.github.kezhenxu94.playground.java.serialization;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * <pre>
 * 
 * 1. 一个类的父类如果没有默认的无参构造函数, 那么该类不可以被序列化,
 * 否则反序列化时会产生 {@link InvalidClassException}
 * 
 * 2. 当一个类被序列化时, 其父类的字段不会被序列化, 除非其父类也实现了
 * {@link Serializable} 接口且其字段非 transient.
 * 
 * </pre>
 * 
 * @author kezhenxu
 *
 */
public class SuperSubClass {
	
	static class Super {
		int sup;
	}
	
	@SuppressWarnings("serial")
	static class Sub extends Super implements Serializable {
		int sub;
	}
	
	@SuppressWarnings("serial")
	static class SerializableSuper implements Serializable {
		// 加上 transient 该字段也不会被序列化
		int sup;
	}
	
	@SuppressWarnings("serial")
	static class SerializableSub extends SerializableSuper implements Serializable {
		int sub;
	}
	
	public static void main(String[] args) throws Exception {
		Sub sub = new Sub();
		sub.sup = 10;
		sub.sub = 20;
		sub = serializeAndDeserialize(sub);
		System.out.println(sub.sup);
		System.out.println(sub.sub);
		
		SerializableSub serializableSub = new SerializableSub();
		serializableSub.sup = 10;
		serializableSub.sub = 20;
		serializableSub = serializeAndDeserialize(serializableSub);
		System.out.println(serializableSub.sup);
		System.out.println(serializableSub.sub);
	}
	
	@SuppressWarnings("unchecked")
	private static <T> T serializeAndDeserialize(T t) throws IOException, ClassNotFoundException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		oos.writeObject(t);
		
		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bais);
		t = (T) ois.readObject();
		
		return t;
	}
}
